package com.quanyan.ic.http.service.impl;

import com.quanyan.ic.cache.OrderMsgDao;
import com.quanyan.ic.cache.PlaceLightSettingDao;
import com.quanyan.ic.common.http.APIResponse;
import com.quanyan.ic.common.http.exception.BizException;
import com.quanyan.ic.common.model.OrderMessage;
import com.quanyan.ic.common.paging.Limit;
import com.quanyan.ic.common.paging.PageResult;
import com.quanyan.ic.http.dao.LightAlarmMapper;
import com.quanyan.ic.http.dao.entry.LightAlarmEntry;
import com.quanyan.ic.http.entity.req.ReqQuerySiteOrderStatus;
import com.quanyan.ic.http.entity.req.ReqSendLightCmd;
import com.quanyan.ic.http.entity.resp.RespSiteOrderStatus;
import com.quanyan.ic.http.service.LightControlService;
import com.quanyan.ic.model.PlaceLightSetting;
import com.quanyan.ic.protocol.LightCmd;
import com.quanyan.ic.protocol.codec.protobuf.ICMessageBuilder;
import com.quanyan.ic.protocol.codec.protobuf.ICMessageProto;
import com.quanyan.ic.protocol.server.LightServer;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by zhuo.shi on 2017/5/31.
 */
@Service
public class LightControlServiceImpl implements LightControlService {

    @Autowired
    private PlaceLightSettingDao placeLightSettingDao;

    @Autowired
    private OrderMsgDao orderMsgDao;
    @Autowired
    private LightAlarmMapper lightAlarmMapper;

    private static Logger logger = LoggerFactory.getLogger(LightControlServiceImpl.class);

    @Override
    public void setPlaceLightSetting(PlaceLightSetting placeLightSetting) {
        if (placeLightSetting.getStart_time_indoor().compareTo(placeLightSetting.getEnd_time_indoor()) >= 0) {
            throw new BizException("室内场开灯时间必须在关灯时间之前");
        }
        if (placeLightSetting.getStart_time_outdoor().compareTo(placeLightSetting.getEnd_time_outdoor()) >= 0) {
            throw new BizException("室外场开灯时间必须在关灯时间之前");
        }
        if (placeLightSetting.getOn_light_before_order_start() < 0) {
            throw new BizException("订单开始前自动开灯时间必须大于0");
        }
        if (placeLightSetting.getOff_light_after_order_end() < 0) {
            throw new BizException("订单开始前自动关灯时间必须大于0");
        }
        placeLightSettingDao.setLightControlSetting(placeLightSetting.getPid(), placeLightSetting);
    }

    @Override
    public RespSiteOrderStatus querySiteOrderStatus(ReqQuerySiteOrderStatus req) {
        int placeId = req.getPlaceId();
        List<Integer> siteIds = req.getSiteIds();
        Long queryTime = req.getQueryTime();
        if (queryTime == null) {
            queryTime = System.currentTimeMillis();
        }
        Map<Integer, Boolean> map = new HashMap<>();
        for (Integer siteId : siteIds) {
            map.put(siteId, orderMsgDao.isOrderTimeSegment(placeId, siteId, queryTime));
        }

        RespSiteOrderStatus resp = new RespSiteOrderStatus();
        resp.setPlaceId(placeId);
        resp.setQueryTime(queryTime);
        resp.setSiteStatusMap(map);
        return resp;
    }

    @Override
    public PageResult<List<LightAlarmEntry>> queryLightAlarms(Map<String, Object> params) {

        Object cityId = params.get("cityId");
        if (cityId == null || StringUtils.isEmpty(cityId) || Integer.valueOf(cityId.toString()) == 0) {
            params.remove("cityId");
        }
        Object placeName = params.get("placeName");
        if (placeName != null && !StringUtils.isEmpty(placeName.toString())) {
            params.put("placeName", "%" + placeName.toString() + "%");
        }

        if (params.get("startDate") != null) {
            String startDate = String.valueOf(params.get("startDate"));
            params.put("startDate", startDate.replaceAll("-", ""));
        }
        if (params.get("endDate") != null) {
            String startDate = String.valueOf(params.get("endDate"));
            params.put("endDate", startDate.replaceAll("-", ""));
        }

        Object pageNo = params.get("pageNum");
        Object pageSize = params.get("pageSize");
        if (pageNo == null) {
            pageNo = 1;
        }
        if (pageSize == null) {
            pageSize = 20;
        }
        int total = lightAlarmMapper.countLightAlarmList(params);
        List<LightAlarmEntry> list = lightAlarmMapper.queryLightAlarmList(params,
                Limit.build(Integer.valueOf(pageNo.toString()), Integer.valueOf(pageSize.toString())));
        return PageResult.create(
                total, Integer.valueOf(pageNo.toString()), Integer.valueOf(pageSize.toString()), list);
    }

    @Override
    public void sendLightCmd(ReqSendLightCmd sendLightCmd) {
        Integer placeId = sendLightCmd.getPlaceId();
        Channel channel = LightServer.getSessionChannelMap().get(String.valueOf(placeId));
        if (channel == null) {
            logger.warn("sendLightCmd, placeId={}, client is closed", placeId);
            return;
        }
        OrderMessage orderMessage = new OrderMessage();
        orderMessage.setPlaceId(placeId);
        orderMessage.setOrderStatus((byte) -1);
        orderMessage.setOrderNo("BLANK");
        orderMessage.setStartTime(0L);
        orderMessage.setEndTime(0L);
        orderMessage.setSiteType(-1);
        orderMessage.setSource((byte) -1);
        List<Integer> siteIds = sendLightCmd.getSiteIds();
        for (Integer siteId : siteIds) {
            orderMessage.setSiteId(siteId);
            if (!channel.isActive()) {
                continue;
            }
            ICMessageProto.ICMessage icMessage = ICMessageBuilder.buildBizICMessage(orderMessage, sendLightCmd.getLightCmd() == 0 ? LightCmd.OFF : LightCmd.ON);
            channel.writeAndFlush(icMessage);
            logger.info("send {} to placeId={}, siteId={}, of client {}", placeId, siteId, channel.remoteAddress());
        }
    }
}
